package jus.aor.printing;

import java.net.*;
import java.util.logging.Logger;
import java.io.*;

import jus.aor.printing.Level;
import jus.aor.printing.Notification;

import static jus.aor.printing.Notification.*;

/**
 * Représentation du Client du serveur d'impression.
 *
 * @author Morat
 */
public class Client {

    public int MAX_LEN_BUFFER = 1024;
    /**
     * 1 second timeout for waiting replies
     */
    protected static final int TIMEOUT = 1000;
    /**
     * la machine supportant le serveur d'impression
     */
    private String host = "localhost";
    /**
     * le port d'installation du serveur d'impression
     */
    private int port = 3000;
    /**
     * le listener est-il vivant
     */
    private boolean alive = true;
    /**
     * le logger du client
     */
    private Logger log = Logger.getLogger("Jus.Aor.Printing.Client", "jus.aor.printing.Client");
    /**
     * l'interfaçage avec la console du client
     */
    private ClientGUI GUI;

    /**
     * construction d'un client
     */
    public Client() {
        GUI = new ClientGUI(this);
        log.setLevel(Level.INFO_2);
    }

    public void queryJobs(JobKey job) {
        System.out.println("query job?");
    }

    public void queryStatus() {
        System.out.println("QueryStatus");
        this.onePrint(null);
    }

    public void multiPrint(File f) {
        System.out.println("Multi Print!");
        this.onePrint(f);
    }

    /**
     * @param key la cle du du job
     * @throws IOException
     */
    private void jobTerminated(JobKey key) throws IOException {
        GUI.removePrintList(key);
    }

    /**
     * Fixe le remote host
     *
     * @param host le remote host supportant le serveur d'impression
     */
    public void setHost(String host) {
        this.host = host;
    }

    /**
     * Fixe le port du serveur d'impression
     *
     * @param port le port supportant le serveur d'impression
     */
    public void setPort(int port) {
        this.port = port;
    }

    /**
     * protocole de print d'un fichier
     *
     * @param f le fichier à imprimer
     */
    private void onePrint(File f) {
        Socket soc = null;
        try (InputStream fis = new FileInputStream(f)) {
            //------------------------------------------------------------
            System.out.println("lancement requete impression");
            soc = new Socket(host, port);
            TCP.writeProtocole(soc, QUERY_PRINT); // on lance une requête d'impression.
            System.out.println("requete envoyé, envoi du jobkey.");
            JobKey job = new JobKey();
            TCP.writeJobKey(soc, job);
            System.out.print("Jobkey envoyé \n Attente notification");
            Notification notif = TCP.readProtocole(soc);
            System.out.print(" -> Notifcation reçu \n Attente jobkey");
            JobKey jobRecu = TCP.readJobKey(soc);  // on recupere le jobKey

            System.out.println("transferé!");
            if (job.equals(jobRecu)) {
                switch (notif) {
                    case REPLY_PRINT_OK:
                        System.out.println("reusiste!");
                        break;
                    default:
                        System.out.println("impossible d'imprimer.");
                }
            } else {
                log.log(Level.WARNING, "Client.QueryPrint.Failed");
            }
            soc.close();
            Socket socSpool = new Socket(host, 2000);
            TCP.writeData(socSpool, fis, MAX_LEN_BUFFER);
            
            
        } catch (NumberFormatException e) {
            log.log(Level.SEVERE, "Client.QueryPrint.Port.Error", e.getMessage());
        } catch (UnknownHostException e) {
            log.log(Level.SEVERE, "Client.QueryPrint.Remote.Error", e.getMessage());
        } catch (IOException e) {
            log.log(Level.SEVERE, "Client.QueryPrint.IO.Error", e.getMessage());
        }
    }

    /**
     * @param args
     */
    public static void main(String args[]) {
        new Client();
    }
}
